<!--
 * @Description: 树组件，可编辑
 * @Author:
 * @Date:
 * @LastEditors: dh
 * @LastEditTime: 2022-10-27 15:12:07
 -->
<template>
	<!-- :current-node-key="treeData[0][treeConfig.id]" -->
	<el-scrollbar>
		<el-tree
			ref="tree"
			class="data_tree"
			:data="treeData"
			:lazy="lazy"
			:load="loadNodeFun"
			:show-checkbox="showCheckbox"
			:default-expand-all="expandAll"
			:highlight-current="!noHighNode"
			:expand-on-click-node="clickNodeExpand"
			:props="treeConfig"
			:check-on-click-node="checkOnClickNode"
			:node-key="treeConfig.id"
			:default-expanded-keys="defaultExpandedKeys"
			@node-click="nodeClick"
			@node-contextmenu="rightClick"
			@check="getCheckNode"
			@node-expand="nodeExpand"
			@node-collapse="nodeCollapse"
		>
			<span slot-scope="{ node, data }" class="custom-tree-node" style="position: relative">
				<span class="el-icon-s-home">{{ node.label }}</span>
				<transition name="fade">
					<div v-if="data[treeConfig.id] == currentIndex[treeConfig.id]" id="tree_tip" ref="treeTip" class="tree_tip" style="top: ; left: ">
						<span @click.stop="() => append(data)">新增子节点</span>
						<span @click.stop="() => edit(data)">编辑名称</span>
						<span @click.stop="() => remove(data)">删除该节点</span>
					</div>
				</transition>
			</span>
		</el-tree>
	</el-scrollbar>
</template>

<script>
/* eslint-disable */

export default {
	// 指定组件上的v-model用$emit什么事件触发，默认input
	model: {
		event: "node",
		prop: "checkNode",
	},
	props: {
		treeData: {
			type: Array,
			default: () => [],
		},
		// 懒加载
		lazy: {
			type: Boolean,
			default: false,
		},
		// 懒加载方法
		loadNodeFun: {
			type: Function,
		},
		// 是否右键事件
		noConfig: {
			type: Boolean,
			default: false,
		},
		// 树配置
		treeConfig: {
			type: Object,
			default: () => {},
		},
		// 高亮选中节点
		noHighNode: {
			type: Boolean,
			default: false,
		},
		// 显示复选框
		showCheckbox: {
			type: Boolean,
			default: false,
		},
		// 默认展开全部
		expandAll: {
			type: Boolean,
			default: false,
		},
		// 点击节点前的图标才展开，false 点击图标展开 true点击节点展开
		clickNodeExpand: {
			type: Boolean,
			default: false,
		},
		// 点击节点时勾选节点，复选框下才生效
		checkOnClickNode: {
			type: Boolean,
			default: false,
		},
		// v-model 双相绑定的数据
		checkNode: [Array, Object],
	},
	data() {
		return {
			currentIndex: {},
			defaultExpandedKeys: [],
		};
	},
	watch: {
		treeData: {
			handler() {
				this.$nextTick(() => {
					if (this.treeData.length > 0) this.$refs.tree.setCurrentNode(this.treeData[0]);
				});
			},
			immediate: true,
		},
	},
	mounted() {
		console.log(this.$options);
		console.log(this.$data);
	},
	methods: {
		// 右键弹出菜单
		rightClick(event, node) {
			window.clearInterval(this.treeMenu);
			if (this.noConfig) return;
			this.currentIndex = node;
			this.$nextTick(() => {
				this.$refs.treeTip.style.left = event.clientX + "px";
				if (window.innerHeight - event.clientY < 150) {
					this.$refs.treeTip.style.top = event.clientY - 95 + "px";
				} else {
					this.$refs.treeTip.style.top = event.clientY + "px";
				}
			});
			// 600ms反应时间，保证右键弹出框不会因为鼠标移开而马上消失
			this.treeMenu = window.setTimeout(() => {
				document.onmousemove = e => {
					const left = document.getElementById("tree_tip").offsetLeft;
					const width = document.getElementById("tree_tip").offsetWidth;
					const top = document.getElementById("tree_tip").offsetTop;
					const height = document.getElementById("tree_tip").offsetHeight;
					if (e.clientX < left - 5 || e.clientX > left + width + 5 || e.clientY < top - 5 || e.clientY > top + height + 5) {
						document.onmousemove = null;
						this.currentIndex = {};
					}
				};
			}, 600);
		},
		// 新增节点
		append(data) {
			this.$emit("append", data);
		},
		// 编辑节点
		edit(data) {
			this.$emit("edit", data);
		},
		// 移除节点
		remove(data) {
			this.$confirm("确认删除?", "提示", {
				confirmButtonText: "确定",
				cancelButtonText: "取消",
				type: "warning",
			}).then(() => {
				this.$emit("remove", data);
			});
		},
		// 点击节点
		nodeClick(data) {
			this.$emit("node", data); // 传回v-model
			document.onmousemove = null; // 防止事件未清除
		},
		// 复选框点击，获取节点
		getCheckNode(node, checkedNodes) {
			// console.log(node);//当前点击的复选框节点
			// console.log(checkedNodes); //checkedNodes、checkedKeys、halfCheckedNodes、halfCheckedKeys 四个属性
			this.$emit("checkNode", checkedNodes);
		},
		// 设置节点选中 回显
		setCheckNodeByKeys(keys) {
			this.$refs.tree.setCheckedKeys([]); // 先清空选中状态
			keys.forEach((i, n) => {
				let node = this.$refs.tree.getNode(i);
				if (node.isLeaf) this.$refs.tree.setChecked(node, true);
			});
		},
		// 获取选中节点 getCheckedNodes getHalfCheckedNodes//getCheckedKeys getHalfCheckedKeys
		getCheckedNodesByKeys() {
			return [...this.$refs.tree.getCheckedKeys(), ...this.$refs.tree.getHalfCheckedKeys()];
		},
		// 节点展开时触发
		nodeExpand(data, node, event) {
			this.defaultExpandedKeys.push(data[this.treeConfig.id]);
		},
		// 节点关闭时始触发
		nodeCollapse(data, node, event) {
			this.defaultExpandedKeys = this.defaultExpandedKeys.filter(v => v != data[this.treeConfig.id]);
		},
		/* 一下是选中一个节点后，当前节点的根节点下左右节点可选，其余根节点下元素全禁用 */
		// 树复选框改变
		checkChange(data, param) {
			this.selectedkeys = param.checkedKeys;
			// 获取子节点
			this.selectCitys = this.$refs.tree.getCheckedNodes(true);
			this.disableCity(data);
		},
		// 树禁用节点
		disableCity(data) {
			const node = this.$refs.tree.getNode(data);
			this.selectedkeys = this.$refs.tree.getCheckedKeys();
			this.parentNode = this.getParentNode(node);
			const id = this.parentNode.key;
			const flag = !!this.selectedkeys.length;
			// this.data 树数据
			this.data.forEach(v => {
				if (v[this.treeConfig.id] !== id) {
					this.$set(v, "disabled", flag);
					const children = v[this.treeConfig.children];
					if (children && children.length) {
						children.forEach(item => {
							this.$set(item, "disabled", flag);
						});
					}
				}
			});
		},
		// 复选框改变获取一级节点
		getParentNode(node) {
			return node.level === 1 ? node : this.getParentNode(node.parent);
		},
	},
};
</script>
<style lang="scss">
/* 解决使用el-scrollbar不出现横向滚动条*/
.el-tree {
	display: inline-block;
	min-width: 100%;
}

.data_tree {
	height: 100%;
	overflow: auto;
	.el-tree-node__content {
		height: 40px;
	}
	.fade-enter-active,
	.fade-leave-active {
		transition: opacity 0.4s;
	}
	.fade-enter,
	.fade-leave-to {
		opacity: 0;
	}
	&.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
		background-color: teal !important;
		color: #fff;
	}
	.el-tree-node__content {
		&:hover {
			background: deeppink;
		}
	}
	.el-tree-node:focus > .el-tree-node__content {
		background-color: orange;
	}
	/* 菜单 */
	.tree_tip {
		color: #666;
		position: fixed;
		background: #fff;
		display: flex;
		flex-direction: column;
		border-radius: 2px;
		z-index: 11;
		box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.3);
		span {
			height: 32px;
			line-height: 32px;
			padding: 0 20px;
			border-radius: 2px;
			transition: all 0.5s;
		}
		span:hover {
			background: #0e3d9c;
			color: #fff;
		}
	}
}
</style>
